#pragma once
#include "CSession.hpp"
#include "Singleton.hpp"
#include "data.hpp"
#include <condition_variable>
#include <functional>
#include <json/value.h>
#include <map>
#include <memory>
#include <mutex>
#include <queue>
#include <thread>
#include <vector>
struct LogicNode {
  std::shared_ptr<CSession> _session;
  std::shared_ptr<MessageNode> _recvnode;
  LogicNode(std::shared_ptr<CSession> session,
            std::shared_ptr<MessageNode> recvnode);
};

class LogicSystem : public Singleton<LogicSystem> {
  friend class Singleton<LogicSystem>;

public:
  ~LogicSystem();
  void PostMsgToQue(std::shared_ptr<LogicNode> msg);
  void DealMsg();

private:
  bool _b_stop;
  std::thread _worker_thread;
  std::condition_variable _consume;
  std::mutex _mutex;
  std::queue<std::shared_ptr<LogicNode>> _msg_que;
  std::map<int, std::function<void(std::shared_ptr<LogicNode>)>> _fun_callbacks;

private:
  LogicSystem();
  void RegisterCallBacks();
  void LoginHandler(std::shared_ptr<LogicNode>);
  void UserSearchHandler(std::shared_ptr<LogicNode>);
  void AddFriendHandler(std::shared_ptr<LogicNode>);
  void AgreeFriendHandler(std::shared_ptr<LogicNode>);
  void SendMessageHandler(std::shared_ptr<LogicNode>);
  void SureMessageHandler(std::shared_ptr<LogicNode>);
  bool GetBaseInfo(std::shared_ptr<CSession>, std::string base_key, int uid,
                   std::shared_ptr<UserInfo> userInfo);
  bool GetFriendApplyInfo(int, std::vector<std::shared_ptr<FriendApplyInfo>> &);
  bool isPureDigit(std::string);
  void GetUserByUid(std::string, Json::Value &);
  void GetUserName(std::string, Json::Value &);
  bool GetFriends(int, std::vector<std::shared_ptr<FriendInfo>> &);
};